#pragma once
#ifndef LIT__EDITOR__MESH__CONVERTER__HH__
#define LIT__EDITOR__MESH__CONVERTER__HH__

#include <OgreMeshManager.h>
#include <LitExceptions.h>
#include <LitEditorPrerequisites.h>
#include <LitFileParser.h>
#include <LitFileSystem.h>
#include <string>

namespace Lit
{
	namespace Editor
	{
		class LIT_API MeshConverterException : public RuntimeError
		{
		public:
			MeshConverterException( const std::string &filename, const std::string &reason, const std::string &func, size_t line, const std::string &file )
				: RuntimeError( Lit::EXC_RUNTIME_ERROR, "Cannot convert mesh '"+filename+"' to Ogre::Mesh because:\r\n"+reason, func, line, file )
			{}
			~MeshConverterException()
			{}
		};
		class LIT_API MeshFormatException : public RuntimeError
		{
		public:
			MeshFormatException( const std::string &ext, const std::string &operation, const std::string &reason, const std::string &func, size_t line, const std::string &file )
				: RuntimeError( Lit::EXC_RUNTIME_ERROR, "Cannot "+operation+" mesh converter format '"+ext+"' because: \r\n"+reason, func, line, file )
			{}
			~MeshFormatException()
			{}
		};
		class LIT_API MeshConverter
		{
		public:
			class Format;

		protected:
			std::vector<Format*> mFormats;

		public:
			MeshConverter();
			~MeshConverter();
			
			std::string getFormatsAsString( bool import_, bool export_ ) const;

			std::vector<Format*>& getFormats();
			const std::vector<Format*>& getFormats() const;
			
			const Format* getFormat( const std::string &ext ) const;
			Format* getFormat( const std::string &ext );

			bool hasFormat( const std::string &ext ) const;

			Format* addFormat( Format * fmt );
			bool destroyFormat( const std::string &ext );

			void clearFormats();
			
			Ogre::MeshPtr importMesh( const std::string &input_filename );
			void exportMesh( const std::string &output_filename, Ogre::MeshPtr mesh );
		};

		class LIT_API MeshConverter::Format
		{
			std::string		mExtension;
			bool			mCanImport;
			bool			mCanExport;
			std::string		mName;
		public:
			Format( const std::string &name, const std::string &extension, bool canImport, bool canExport );
			virtual ~Format();
			
			const std::string &		getExtension() const;
			const std::string &		getName() const;

			bool	canImport() const;
			bool	canExport() const;

			static std::string eatLeft( const std::string &str, size_t num = 1 );
			static std::string trim( const std::string &str, bool left = true, bool right = true );

			
			virtual Ogre::MeshPtr importMesh( const std::string &input_filename, const std::string &ogre_mesh_name ) = 0;
			virtual void exportMesh( const std::string &output_filename, Ogre::MeshPtr mesh ) = 0;
		};

		LIT_API std::ostream& operator << ( std::ostream& strm, const MeshConverter::Format& fmt );

	};
};

#endif